package amtf

import (
	"fmt"
	"reflect"
	"regexp"
	"strings"

	"github.com/iancoleman/strcase"
)

func A取一对一或多的关联组件(字段 *S字段) (关联组件 *S组件) {
	if 字段.A类型 == A字段类型_关联字段 {
		关联类型, 关联组件 := A解关联属性(字段)
		if 关联类型 != A关联类型_属于 {
			return 关联组件
		}
	}
	return nil
}

func A解关联属性(字段 *S字段) (关联类型 string, 关联组件 *S组件) {
	关联属性 := A解对象(字段.A关联属性)
	关联组件id := 关联属性["关联组件id"]
	关联类型 = 关联属性["关联类型"]
	关联组件 = A组件集[关联组件id]
	return
}

func A取外键关联组件(字段 *S字段) (关联组件 *S组件) {
	关联组件id := A成组件id(字段.A关联插件名, 字段.A关联组件名)
	关联组件 = A组件集[关联组件id]
	return
}

func A打印models(models any) {
	modelsValue := A取反射el(reflect.ValueOf(models))
	if modelsValue.Kind() == reflect.Slice {
		for i := 0; i < modelsValue.Len(); i++ {
			element := modelsValue.Index(i)
			if element.Kind() == reflect.Ptr {
				element = element.Elem()
			}
			fmt.Printf("%d: %+v\n", i, element.Interface())
		}
	}
}

// func A成model全名(组件 *S组件) (res string) {
// 	res = 组件.A插件名 + "." + A成model名_go(组件)
// 	组件.Amodel英文全名 = res
// 	return
// }

func A成model名(组件 *S组件) (res string) {
	// res = 组件.A插件名 + "_" + 组件.A名称 + "model"
	res = 组件.A插件名 + "之" + 组件.A名称 + "model"
	// res = 组件.A名称 + "model"
	return
}

func A成model名_go(组件 *S组件) (res string) {
	// res = "S" + 组件.A插件名 + "_" + 组件.A名称 + "model"
	组件.Amodel名 = A成model名(组件)
	res = "S" + 组件.Amodel名
	组件.Amodel英文名 = res
	// 组件.Amodel英文全名 = 组件.A插件英文名 + "." + 组件.Amodel英文名
	组件.Amodel英文全名 = "aa_model" + "." + 组件.Amodel英文名
	return
}

func A成表名(组件 *S组件) {
	if 组件.A表名 == "" {
		组件.A表名 = 组件.A插件名 + "_" + 组件.A名称
	}
}

// func A成表名(插件名 string, 组件名 string) (res string) {
// 	res = 插件名 + "_" + 组件名
// 	return
// }

func A成字段id_从组件(组件 *S组件, 字段名 string) (id string) {
	// id = 插件名 + "." + 组件名 + "." + 字段名
	return A成字段id(组件.A插件名, 组件.A名称, 字段名)
}

func A成字段id(插件名 string, 组件名 string, 字段名 string) (id string) {
	id = 插件名 + "." + 组件名 + "." + 字段名
	return
}

func A成组件id_从自己(组件 *S组件) (id string) {
	return A成组件id(组件.A插件名, 组件.A名称)
}

func A成组件id(插件名 string, 组件名 string) (id string) {
	id = 插件名 + "." + 组件名
	return
}

func A取字段(str string) (组件 *S组件, 字段 *S字段) {
	_, 组件id, 字段id := A拆分并合成字段id(str)
	组件 = A组件集[组件id]
	字段 = A字段集[字段id]
	return
}

func A拆分并合成字段id(str string) (插件id string, 组件id string, 字段id string) {
	插件名, 组件名, 字段名 := A拆分字段id(str)
	插件id = 插件名
	组件id = A成组件id(插件名, 组件名)
	字段id = A成字段id(插件名, 组件名, 字段名)
	return
}

func A拆分字段id(str string) (插件名 string, 组件名 string, 字段名 string) {
	sps := strings.Split(str, ".")
	插件名 = sps[0]
	组件名 = sps[1]
	字段名 = sps[2]
	return
}

func A拆分组件id(str string) (split []string) {
	split = strings.Split(str, ".")
	return
}

func A成字段名称(字段 *S字段) {
	if 字段.A名称go == "" {
		// 1. 判断是否以中文开头
		reg := regexp.MustCompile(`^[\p{Han}]`)
		if reg.MatchString(字段.A名称) {
			字段.A名称go = "A" + 字段.A名称
			字段.A名称sql = 字段.A名称
		} else {
			// 2. 非中文开头：驼峰转下划线
			小写 := strcase.ToSnake(字段.A名称)
			大驼峰 := strcase.ToCamel(字段.A名称)
			字段.A名称go = 大驼峰
			字段.A名称sql = 小写
		}
	}
}

func A取字段名称go(str string) (字段名称go string) {
	// 1. 判断是否以中文开头
	reg := regexp.MustCompile(`^[\p{Han}]`)
	if reg.MatchString(str) {
		字段名称go = "A" + str
	} else {
		// 2. 非中文开头：驼峰转下划线
		大驼峰 := strcase.ToCamel(str)
		字段名称go = 大驼峰
	}
	return
}
